home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / avr32 / include / asm / uaccess.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  9.6 KB  |  325 lines

  1. /*
  2.  * Copyright (C) 2004-2006 Atmel Corporation
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License version 2 as
  6.  * published by the Free Software Foundation.
  7.  */
  8. #ifndef __ASM_AVR32_UACCESS_H
  9. #define __ASM_AVR32_UACCESS_H
  10.  
  11. #include <linux/errno.h>
  12. #include <linux/sched.h>
  13.  
  14. #define VERIFY_READ    0
  15. #define VERIFY_WRITE    1
  16.  
  17. typedef struct {
  18.     unsigned int is_user_space;
  19. } mm_segment_t;
  20.  
  21. /*
  22.  * The fs value determines whether argument validity checking should be
  23.  * performed or not.  If get_fs() == USER_DS, checking is performed, with
  24.  * get_fs() == KERNEL_DS, checking is bypassed.
  25.  *
  26.  * For historical reasons (Data Segment Register?), these macros are misnamed.
  27.  */
  28. #define MAKE_MM_SEG(s)    ((mm_segment_t) { (s) })
  29. #define segment_eq(a,b)    ((a).is_user_space == (b).is_user_space)
  30.  
  31. #define USER_ADDR_LIMIT 0x80000000
  32.  
  33. #define KERNEL_DS    MAKE_MM_SEG(0)
  34. #define USER_DS        MAKE_MM_SEG(1)
  35.  
  36. #define get_ds()    (KERNEL_DS)
  37.  
  38. static inline mm_segment_t get_fs(void)
  39. {
  40.     return MAKE_MM_SEG(test_thread_flag(TIF_USERSPACE));
  41. }
  42.  
  43. static inline void set_fs(mm_segment_t s)
  44. {
  45.     if (s.is_user_space)
  46.         set_thread_flag(TIF_USERSPACE);
  47.     else
  48.         clear_thread_flag(TIF_USERSPACE);
  49. }
  50.  
  51. /*
  52.  * Test whether a block of memory is a valid user space address.
  53.  * Returns 0 if the range is valid, nonzero otherwise.
  54.  *
  55.  * We do the following checks:
  56.  *   1. Is the access from kernel space?
  57.  *   2. Does (addr + size) set the carry bit?
  58.  *   3. Is (addr + size) a negative number (i.e. >= 0x80000000)?
  59.  *
  60.  * If yes on the first check, access is granted.
  61.  * If no on any of the others, access is denied.
  62.  */
  63. #define __range_ok(addr, size)                        \
  64.     (test_thread_flag(TIF_USERSPACE)                \
  65.      && (((unsigned long)(addr) >= 0x80000000)            \
  66.          || ((unsigned long)(size) > 0x80000000)            \
  67.          || (((unsigned long)(addr) + (unsigned long)(size)) > 0x80000000)))
  68.  
  69. #define access_ok(type, addr, size) (likely(__range_ok(addr, size) == 0))
  70.  
  71. /* Generic arbitrary sized copy. Return the number of bytes NOT copied */
  72. extern __kernel_size_t __copy_user(void *to, const void *from,
  73.                    __kernel_size_t n);
  74.  
  75. extern __kernel_size_t copy_to_user(void __user *to, const void *from,
  76.                     __kernel_size_t n);
  77. extern __kernel_size_t copy_from_user(void *to, const void __user *from,
  78.                       __kernel_size_t n);
  79.  
  80. static inline __kernel_size_t __copy_to_user(void __user *to, const void *from,
  81.                          __kernel_size_t n)
  82. {
  83.     return __copy_user((void __force *)to, from, n);
  84. }
  85. static inline __kernel_size_t __copy_from_user(void *to,
  86.                            const void __user *from,
  87.                            __kernel_size_t n)
  88. {
  89.     return __copy_user(to, (const void __force *)from, n);
  90. }
  91.  
  92. #define __copy_to_user_inatomic __copy_to_user
  93. #define __copy_from_user_inatomic __copy_from_user
  94.  
  95. /*
  96.  * put_user: - Write a simple value into user space.
  97.  * @x:   Value to copy to user space.
  98.  * @ptr: Destination address, in user space.
  99.  *
  100.  * Context: User context only.  This function may sleep.
  101.  *
  102.  * This macro copies a single simple value from kernel space to user
  103.  * space.  It supports simple types like char and int, but not larger
  104.  * data types like structures or arrays.
  105.  *
  106.  * @ptr must have pointer-to-simple-variable type, and @x must be assignable
  107.  * to the result of dereferencing @ptr.
  108.  *
  109.  * Returns zero on success, or -EFAULT on error.
  110.  */
  111. #define put_user(x,ptr)    \
  112.     __put_user_check((x),(ptr),sizeof(*(ptr)))
  113.  
  114. /*
  115.  * get_user: - Get a simple variable from user space.
  116.  * @x:   Variable to store result.
  117.  * @ptr: Source address, in user space.
  118.  *
  119.  * Context: User context only.  This function may sleep.
  120.  *
  121.  * This macro copies a single simple variable from user space to kernel
  122.  * space.  It supports simple types like char and int, but not larger
  123.  * data types like structures or arrays.
  124.  *
  125.  * @ptr must have pointer-to-simple-variable type, and the result of
  126.  * dereferencing @ptr must be assignable to @x without a cast.
  127.  *
  128.  * Returns zero on success, or -EFAULT on error.
  129.  * On error, the variable @x is set to zero.
  130.  */
  131. #define get_user(x,ptr) \
  132.     __get_user_check((x),(ptr),sizeof(*(ptr)))
  133.  
  134. /*
  135.  * __put_user: - Write a simple value into user space, with less checking.
  136.  * @x:   Value to copy to user space.
  137.  * @ptr: Destination address, in user space.
  138.  *
  139.  * Context: User context only.  This function may sleep.
  140.  *
  141.  * This macro copies a single simple value from kernel space to user
  142.  * space.  It supports simple types like char and int, but not larger
  143.  * data types like structures or arrays.
  144.  *
  145.  * @ptr must have pointer-to-simple-variable type, and @x must be assignable
  146.  * to the result of dereferencing @ptr.
  147.  *
  148.  * Caller must check the pointer with access_ok() before calling this
  149.  * function.
  150.  *
  151.  * Returns zero on success, or -EFAULT on error.
  152.  */
  153. #define __put_user(x,ptr) \
  154.     __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
  155.  
  156. /*
  157.  * __get_user: - Get a simple variable from user space, with less checking.
  158.  * @x:   Variable to store result.
  159.  * @ptr: Source address, in user space.
  160.  *
  161.  * Context: User context only.  This function may sleep.
  162.  *
  163.  * This macro copies a single simple variable from user space to kernel
  164.  * space.  It supports simple types like char and int, but not larger
  165.  * data types like structures or arrays.
  166.  *
  167.  * @ptr must have pointer-to-simple-variable type, and the result of
  168.  * dereferencing @ptr must be assignable to @x without a cast.
  169.  *
  170.  * Caller must check the pointer with access_ok() before calling this
  171.  * function.
  172.  *
  173.  * Returns zero on success, or -EFAULT on error.
  174.  * On error, the variable @x is set to zero.
  175.  */
  176. #define __get_user(x,ptr) \
  177.     __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
  178.  
  179. extern int __get_user_bad(void);
  180. extern int __put_user_bad(void);
  181.  
  182. #define __get_user_nocheck(x, ptr, size)                \
  183. ({                                    \
  184.     unsigned long __gu_val = 0;                    \
  185.     int __gu_err = 0;                        \
  186.                                     \
  187.     switch (size) {                            \
  188.     case 1: __get_user_asm("ub", __gu_val, ptr, __gu_err); break;    \
  189.     case 2: __get_user_asm("uh", __gu_val, ptr, __gu_err); break;    \
  190.     case 4: __get_user_asm("w", __gu_val, ptr, __gu_err); break;    \
  191.     default: __gu_err = __get_user_bad(); break;            \
  192.     }                                \
  193.                                     \
  194.     x = (typeof(*(ptr)))__gu_val;                    \
  195.     __gu_err;                            \
  196. })
  197.  
  198. #define __get_user_check(x, ptr, size)                    \
  199. ({                                    \
  200.     unsigned long __gu_val = 0;                    \
  201.     const typeof(*(ptr)) __user * __gu_addr = (ptr);        \
  202.     int __gu_err = 0;                        \
  203.                                     \
  204.     if (access_ok(VERIFY_READ, __gu_addr, size)) {            \
  205.         switch (size) {                        \
  206.         case 1:                            \
  207.             __get_user_asm("ub", __gu_val, __gu_addr,    \
  208.                        __gu_err);            \
  209.             break;                        \
  210.         case 2:                            \
  211.             __get_user_asm("uh", __gu_val, __gu_addr,    \
  212.                        __gu_err);            \
  213.             break;                        \
  214.         case 4:                            \
  215.             __get_user_asm("w", __gu_val, __gu_addr,    \
  216.                        __gu_err);            \
  217.             break;                        \
  218.         default:                        \
  219.             __gu_err = __get_user_bad();            \
  220.             break;                        \
  221.         }                            \
  222.     } else {                            \
  223.         __gu_err = -EFAULT;                    \
  224.     }                                \
  225.     x = (typeof(*(ptr)))__gu_val;                    \
  226.     __gu_err;                            \
  227. })
  228.  
  229. #define __get_user_asm(suffix, __gu_val, ptr, __gu_err)            \
  230.     asm volatile(                            \
  231.         "1:    ld." suffix "    %1, %3            \n"    \
  232.         "2:                        \n"    \
  233.         "    .section .fixup, \"ax\"            \n"    \
  234.         "3:    mov    %0, %4                \n"    \
  235.         "    rjmp    2b                \n"    \
  236.         "    .previous                \n"    \
  237.         "    .section __ex_table, \"a\"        \n"    \
  238.         "    .long    1b, 3b                \n"    \
  239.         "    .previous                \n"    \
  240.         : "=r"(__gu_err), "=r"(__gu_val)            \
  241.         : "0"(__gu_err), "m"(*(ptr)), "i"(-EFAULT))
  242.  
  243. #define __put_user_nocheck(x, ptr, size)                \
  244. ({                                    \
  245.     typeof(*(ptr)) __pu_val;                    \
  246.     int __pu_err = 0;                        \
  247.                                     \
  248.     __pu_val = (x);                            \
  249.     switch (size) {                            \
  250.     case 1: __put_user_asm("b", ptr, __pu_val, __pu_err); break;    \
  251.     case 2: __put_user_asm("h", ptr, __pu_val, __pu_err); break;    \
  252.     case 4: __put_user_asm("w", ptr, __pu_val, __pu_err); break;    \
  253.     case 8: __put_user_asm("d", ptr, __pu_val, __pu_err); break;    \
  254.     default: __pu_err = __put_user_bad(); break;            \
  255.     }                                \
  256.     __pu_err;                            \
  257. })
  258.  
  259. #define __put_user_check(x, ptr, size)                    \
  260. ({                                    \
  261.     typeof(*(ptr)) __pu_val;                    \
  262.     typeof(*(ptr)) __user *__pu_addr = (ptr);            \
  263.     int __pu_err = 0;                        \
  264.                                     \
  265.     __pu_val = (x);                            \
  266.     if (access_ok(VERIFY_WRITE, __pu_addr, size)) {            \
  267.         switch (size) {                        \
  268.         case 1:                            \
  269.             __put_user_asm("b", __pu_addr, __pu_val,    \
  270.                        __pu_err);            \
  271.             break;                        \
  272.         case 2:                            \
  273.             __put_user_asm("h", __pu_addr, __pu_val,    \
  274.                        __pu_err);            \
  275.             break;                        \
  276.         case 4:                            \
  277.             __put_user_asm("w", __pu_addr, __pu_val,    \
  278.                        __pu_err);            \
  279.             break;                        \
  280.         case 8:                            \
  281.             __put_user_asm("d", __pu_addr, __pu_val,        \
  282.                        __pu_err);            \
  283.             break;                        \
  284.         default:                        \
  285.             __pu_err = __put_user_bad();            \
  286.             break;                        \
  287.         }                            \
  288.     } else {                            \
  289.         __pu_err = -EFAULT;                    \
  290.     }                                \
  291.     __pu_err;                            \
  292. })
  293.  
  294. #define __put_user_asm(suffix, ptr, __pu_val, __gu_err)            \
  295.     asm volatile(                            \
  296.         "1:    st." suffix "    %1, %3            \n"    \
  297.         "2:                        \n"    \
  298.         "    .section .fixup, \"ax\"            \n"    \
  299.         "3:    mov    %0, %4                \n"    \
  300.         "    rjmp    2b                \n"    \
  301.         "    .previous                \n"    \
  302.         "    .section __ex_table, \"a\"        \n"    \
  303.         "    .long    1b, 3b                \n"    \
  304.         "    .previous                \n"    \
  305.         : "=r"(__gu_err), "=m"(*(ptr))                \
  306.         : "0"(__gu_err), "r"(__pu_val), "i"(-EFAULT))
  307.  
  308. extern __kernel_size_t clear_user(void __user *addr, __kernel_size_t size);
  309. extern __kernel_size_t __clear_user(void __user *addr, __kernel_size_t size);
  310.  
  311. extern long strncpy_from_user(char *dst, const char __user *src, long count);
  312. extern long __strncpy_from_user(char *dst, const char __user *src, long count);
  313.  
  314. extern long strnlen_user(const char __user *__s, long __n);
  315. extern long __strnlen_user(const char __user *__s, long __n);
  316.  
  317. #define strlen_user(s) strnlen_user(s, ~0UL >> 1)
  318.  
  319. struct exception_table_entry
  320. {
  321.     unsigned long insn, fixup;
  322. };
  323.  
  324. #endif /* __ASM_AVR32_UACCESS_H */
  325.